using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;

namespace WebApplication
{
    /// <summary>
    /// Summary description for StockRound.
    /// </summary>
    public partial class StockRound : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
    {
        // runtime variables

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {

        }
        #endregion

        private void InitializeClientCallbacksWithoutPostbacks()
        {
            try
            {
                ClientScriptManager cm = Page.ClientScript;
                String cbReference = cm.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
                String callbackScript = "function CallServer(arg, context) {" + cbReference + "; }";
                cm.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);
            }
            catch (Exception ex)
            {
                DisplayError ("Exception, InitializeClientCallbacksWithoutPostbacks: " + ex.Message);
            }
        }

        public void RaiseCallbackEvent(String eventArgument)
        {
            try
            {
                Game game = Global.getGame(this);
                string sPlayer = Session["PlayerName"] as string;
                Player player = game.Players[sPlayer];
                player.CanPermaPass = false;
                Session["CallbackResult"] = "No Refresh";

                if (player.UpdateScreen || !game.GoToStockRound)
                {
                    player.UpdateScreen = false;

                    if (!game.GoToStockRound)
                    {
                        player.CanPermaPass = false;
                        Session["CallbackResult"] = "Operating Round";
                    }
                    else
                    {
                        player.CanPermaPass = true;
                        Session["CallbackResult"] = "refresh";
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayError("Exception, RaiseCallbackEvent (): " + ex.Message);
            }
        }

        public string GetCallbackResult()
        {
            string sReturn = "";

            try
            {
                sReturn = Session["CallbackResult"] as string;

                if (sReturn == null)
                {
                    sReturn = "";
                }
            }
            catch (Exception ex)
            {
                DisplayError ("Exception, GetCallbackResult: " + ex.Message);
            }

            return sReturn;
        }

        protected void Page_Load(object sender, System.EventArgs e)
        {
            try
            {
                Game game = Global.getGame(this); ;
                string sPlayer = Session["PlayerName"].ToString();
                Player player = game.Players[sPlayer];

                if (!this.IsPostBack)
                {
                    if (this.PermaPass.Checked != player.PermaPass)
                    {
                        this.PermaPass.Checked = player.PermaPass;
                    }
                }

                if (this.IsCallback)
                {
                    return;
                }

                InitializeClientCallbacksWithoutPostbacks();

                SetTitle(sPlayer);
                PriorityCheckBox.Text = sPlayer;

                if (!game.ForcedStockSalePending)
                {
                    if (!game.InStockRound())
                    {
                        player.PermaPass = false;
//                        Response.Redirect("OperatingRound2.aspx");
                        this.Server.Transfer("OperatingRound2.aspx");
                    }
                }

                if (!game.PrivateCompanySale)
                {
                    DisplayStockRoundInfo(game, player);
                }
                else
                {
//                    Response.Redirect("PlayerBuyPrivateCompany.aspx");
                    this.Server.Transfer("PlayerBuyPrivateCompany.aspx");
                }

                if (player.CanPermaPass && player.Priority && player.PermaPass && !player.HasActedDuringStockRound())
                {
                    DoPass(true);
                }
            }
            catch (Exception ex)
            {
                DisplayError ("Exception during Page_Load: " + ex.Message);
            }
        }

        private void DisplayStockRoundInfo(Game game, Player player)
        {
            try
            {
                // handle forced stock sale
                if (game.ForcedStockSalePending)
                {
                    DisplayError ("You must sell stock to raise $" + game.ForcedStockSaleAmountNeeded.ToString() + " and you have sold $" + game.ForcedStockSaleAmountSold.ToString() + " so far.");
                    player.Priority = game.ForcedStockSalePlayer == player;

                    pbDone.Enabled = true;
                    pbPass.Enabled = false;
                }

                FillTableWithCompanyInfo();
                FillTableWithPlayerInfo();

                // hide the cells and row for each company
                for (int i = 0; i < GameInfoTable.Rows.Count; i++)
                {
                    for (int j = 0; j < Game.NumberOfCompanies; j++)
                    {
                        GameInfoTable.Rows[i].Cells[j + 3].Visible = false;
                    }
                }

                // show the cells and row for each open company
                for (int i = 0; i < GameInfoTable.Rows.Count; i++)
                {
                    foreach (PublicCompany company in game.PublicCompanies)
                    {
                        if (company.CompanyAvailable)
                            GameInfoTable.Rows[i].Cells[company.Index + 3].Visible = true;
                    }
                }

                if (player.PurchasedSomething || player.SoldSomething)
                {
                    pbDone.Enabled = true;
                    pbPass.Enabled = false;
                    this.UndoPB.Enabled = true;
                }

                Passes.Text = game.Passes + " passes";
                UpdateHistory(game);
            }
            catch (Exception ex)
            {
                DisplayError ("Exception, DisplayStockRoundInfo:" + ex.Message);
            }
        }


        private void UpdateHistory(Game game)
        {
            // JWF 12.1.2007  The following is copied verbatim from OperatingRound2.aspx.cs
            // Joe: operating round Undo throws exception on DataBind() when there are fewer history lines
            // and the selection index is no longer valid.  So set the selected index down to 0 (it's restored
            // below).
            try
            {
                if (historyLB.SelectedIndex > 0)
                    historyLB.SelectedIndex = 0;

                historyLB.DataSource = game.History;
                historyLB.DataBind();
                historyLB.SelectedIndex = historyLB.Items.Count - 1;
            }
            catch (Exception ex)
            {
                DisplayError("Exception, UpdateHistory: " + ex.Message);
            }
        }

        private void SetTitle(string sNewTitle)
        {
            try
            {
                HtmlGenericControl title = this.FindControl("Title") as HtmlGenericControl;

                if (title != null)
                    title.InnerText = sNewTitle;
            }
            catch (Exception ex)
            {
                DisplayError("Exception, SetTitle: " + ex.Message);
            }
        }

        private void EnableControls(bool bEnable)
        {
            try
            {
                Game game = Global.getGame(this);

                // Joe 12/1/07: When in forced stock sale, enable Done and disable Pass
                pbPass.Enabled = bEnable && (!game.ForcedStockSalePending);
                pbDone.Enabled = /*false*/game.ForcedStockSalePending;	// always until either buy or sell
                this.UndoPB.Enabled = false;  // Undo disabled until a share is bought or sold.

                // Disable refresh for the current player's turn.  Client side script will handle turning on/off the refresh.
                PriorityCheckBox.Enabled = false;
                PriorityCheckBox.Checked = bEnable;
            }
            catch (Exception ex)
            {
                DisplayError("Exception, EnableControls: " + ex.Message);
            }
        }

        private void FillTableWithPlayerInfo()
        {
            try
            {
                Game game = Global.getGame(this); ;
                string sPlayer = Session["PlayerName"].ToString();

                int nRow = 0;
                Player Me = game.Players[sPlayer];
                bool bDoIHavePriority = Me.Priority;	// Is it me?

                foreach (Player player in game.Players)
                {
                    bool bIsItMyTurn = sPlayer == player.Name && player.Priority;	// Is it me?

                    nRow++;
                    // JWF 11.23.2007  If the player is already in the table then reuse the row, otherwise create a new one.  Done to eliminate the need for Page_Reloads.

                    TableRow row = null;
                    TableCell cell = null;
                    cell = GameInfoTable.FindControl("nameOfPlayer" + player.Name) as TableCell;

                    if (cell != null)
                    {
                        row = cell.Parent as TableRow;

                        if (player.Priority)
                        {
                            row.BackColor = System.Drawing.Color.Beige;
                            row.ForeColor = System.Drawing.Color.DarkGreen;
                            cell.Font.Bold = true;
                        }
                        else
                        {
                            row.BackColor = System.Drawing.Color.Transparent;
                            cell.ForeColor = System.Drawing.Color.Blue;
                            cell.Font.Bold = false;
                        }

                        if (player.Name == sPlayer)
                            cell.Font.Italic = true;

                        cell = FindControl("player's cash" + player.Name) as TableCell;

                        if (cell != null)
                        {
                            cell.Text = player.Cash.ToString();
                        }
                        /*            
                                            foreach (TableCell currentCell in row.Cells)
                                            {
                                                if ((currentCell.ID != null) && currentCell.ID.ToLower().StartsWith("player's cash" + player.Name))
                                                {
                                                    currentCell.Text = player.Cash.ToString();
                                                    break;
                                                }
                                            }
                         */

                        player.ResetShareIntraRoundInfo();
                        player.UpdateShareTables();

                        // Now update the player owned shares row.

                        foreach (PublicCompany company in game.PublicCompanies)
                        {
                            bool bEnabled = false;
                            string sCellID;
                            string sShares;
                            string sName = player.Name;
                            string sCompany = company.Name;
                            Button button;

                            sCellID = sName + sCompany + "Shares";
                            cell = GameInfoTable.FindControl(sCellID) as TableCell;
                            button = cell.Controls[0] as Button;

                            //enable the sell shares button
                            bEnabled = bIsItMyTurn && player._nNumShares[company.Index] > 0;
                            button.Enabled = bEnabled;

                            // # shares owned and if president or sold any
                            sShares = player._nNumShares[company.Index].ToString();

                            if (player._bPresShares[company.Index])		// has pres share?
                                sShares += "P";

                            if (player._bSoldShares[company.Index])		// sold shares?
                                sShares += "x";

                            button.Text = sShares;
                        }
                    }
                    else
                    {
                        row = new TableRow();
                        cell = new TableCell();
                        cell.Text = player.Name;

                        if (player.Priority)
                        {
                            row.BackColor = System.Drawing.Color.Beige;
                            row.ForeColor = System.Drawing.Color.DarkGreen;
                            cell.Font.Bold = true;
                        }

                        if (player.Name == sPlayer)
                            cell.Font.Italic = true;

                        cell.ID = "nameOfPlayer" + player.Name;
                        row.Cells.Add(cell);

                        cell = new TableCell();
                        cell.Text = player.Cash.ToString();
                        cell.ID = "player's cash" + player.Name;
                        row.Cells.Add(cell);

                        cell = new TableCell();

                        // add privates to players line
                        foreach (PrivateCompany privateCompany in player.PrivateCompanies)
                        {
                            bool bEnabled;
                            Button button;

                            bEnabled = bDoIHavePriority && sPlayer != player.Name;	// can only buy other players privates

                            button = new Button();
                            button.Text = privateCompany.NickName;
                            button.Click += new System.EventHandler(this.BuyPrivate);
                            button.Enabled = bEnabled && !Me.PurchasedSomething && !game.ForcedStockSalePending;
                            button.CommandName = player.Name;					// owner
                            button.CommandArgument = privateCompany.NickName;	// private
                            button.ToolTip = privateCompany.Name + "\n" + "Cost: " + privateCompany.Cost + "\n" + "Income: " + privateCompany.Income;

                            cell.Controls.Add(button);
                        }

                        row.Cells.Add(cell);

                        // update public shares owned
                        player.ResetShareIntraRoundInfo();
                        player.UpdateShareTables();

                        // add place holder cells for each company
                        for (int i = 0; i < Game.NumberOfCompanies; i++)
                        {
                            cell = new TableCell();
                            cell.Text = "0";
                            row.Cells.Add(cell);
                        }

                        // create placeholder cells for public companies
                        foreach (PublicCompany company in game.PublicCompanies)
                        {
                            int nShares = 0;
                            bool bEnabled = false;
                            string sCellID;
                            string sShares;
                            string sName = player.Name;
                            string sCompany = company.Name;
                            Button button;

                            //cell = new TableCell();
                            cell = row.Cells[company.Index + 3];
                            sCellID = sName + sCompany + "Shares";
                            cell.ID = sCellID;

                            button = new Button();
                            button.Text = nShares.ToString();
                            cell.Controls.Add(button);

                            //enable the sell shares button
                            bEnabled = bIsItMyTurn && player._nNumShares[company.Index] > 0;
                            button.Enabled = bEnabled;
                            button.Click += new System.EventHandler(this.SellShares);
                            button.CommandName = player.Name;
                            button.CommandArgument = sCompany;
                            button.ToolTip = "Sell a share(s) of " + sCompany;

                            // # shares owned and if president or sold any
                            sShares = player._nNumShares[company.Index].ToString();

                            if (player._bPresShares[company.Index])		// has pres share?
                                sShares += "P";

                            if (player._bSoldShares[company.Index])		// sold shares?
                                sShares += "x";

                            button.Text = sShares;
                        }

                        GameInfoTable.Rows.AddAt(nRow, row);
                    }

                    if (player.Priority)
                    {
                        currentPlayersTurn.Text = player.Name;

                        if (sPlayer == player.Name)
                        {
                            currentPlayersTurn.ForeColor = Color.Green;
                            //					    currentPlayersTurn.BackColor = Color.Black;
                            EnableControls(true);
                        }
                        else
                        {
                            currentPlayersTurn.ForeColor = Color.Red;
                            //					    currentPlayersTurn.BackColor = Color.Transparent;
                            EnableControls(false);
                        }

                        // if player is over certificate limit, warn him and disable pass & done until at limit
                        if (player.IsOverCertificateLimit())
                        {
                            DisplayError("You are over the certificate limit and must sell shares.");

                            pbPass.Enabled = false;
                            pbDone.Enabled = false;
                        }

                        for (int i = 0; i < game.PublicCompanies.Count; i++)
                        {
                            if (player.IsOverCompanyShareLimit(i))
                            {
                                DisplayError("You are over the 60% company share limit of " + game.PublicCompanies[i].Name + " and must sell shares.");

                                pbPass.Enabled = false;
                                pbDone.Enabled = false;
                            }
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                DisplayError("Exception, FillTableWithPlayerInfo: " + ex.Message);
            }
        }

        private void FillTableWithCompanyInfo()
        {
            try
            {
                Game game = Global.getGame(this); ;
                string sPlayer = Session["PlayerName"].ToString();
                Player player;

                player = game.Players[sPlayer];

                // set bank amount
                TableCell tableCell;
                tableCell = (TableCell)GameInfoTable.FindControl("BankCash");
                tableCell.Text = game.Bank.ToString();

                // JWF 11.23.2007  Kludge!  The following lines of code are to work around a bug that occurs when we insert the player's the other text gets shifted down.  Overwrite that text with null strings.              

                TableRow tableRow = tableCell.Parent as TableRow;
                tableRow.BackColor = System.Drawing.Color.Transparent;
                tableRow.ForeColor = System.Drawing.Color.Blue;
                tableCell = tableRow.Cells[0];
                tableCell.ForeColor = System.Drawing.Color.Blue;
                tableCell.Font.Italic = false;
                tableCell.Font.Bold = false;

                int nRowIndex = GameInfoTable.Rows.GetRowIndex(tableRow) + 1; // Get the next row

                for (int i = nRowIndex; i <= nRowIndex + game.Players.Count; i++)  // Cycle thru enough rows so that you don't have the cash flowing down.
                {
                    tableRow = GameInfoTable.Rows[i];
                    tableRow.BackColor = System.Drawing.Color.Transparent;
                    tableRow.ForeColor = System.Drawing.Color.Blue;

                    TableCell currentCell = tableRow.Cells[0];
                    currentCell.ForeColor = System.Drawing.Color.Blue;
                    currentCell.Font.Italic = false;
                    currentCell.Font.Bold = false;

                    currentCell = tableRow.Cells[1];
                    currentCell.Text = "";   // Fixes the glitch
                }

                // End of Kludge!

                foreach (PublicCompany company in game.PublicCompanies)
                {
                    int nCash = company.Cash;
                    int nEscrow = company.Escrow;
                    int nLoans = company.Loans;
                    int nTokens = company.Tokens;
                    int nTokensPlayed = company.TokensPlayed;
                    int nParPrice = company.ParPrice;
                    int nCurrentValue = company.MarketValue;
                    int nIPOShares = company.IPOShares.Count;
                    int nBankPoolShares = company.OpenMarketShares.Count;
                    bool bEnabled = false;
                    bool bSoldShares = false;
                    string sTokens = "";
                    string sCompany = company.Name;
                    //				string		sMarketLocation	= "";
                    Button button;

                    // set company name
                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);
                    tableCell.Text = sCompany;

                    // figure out if player sold shares earlier so cant buy until next SR
                    bSoldShares = player._bSoldShares[company.Index];

                    // set company IPO shares
                    sCompany = company.Name;
                    sCompany += "IPO";

                    if (nIPOShares == 9)	// if all 9 certificates aval, show 10 shares
                        nIPOShares++;

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (tableCell.Controls.Count > 0)
                    {
                        button = tableCell.Controls[0] as Button;
                    }
                    else
                    {
                        button = new Button();
                        tableCell.Controls.Add(button);
                        button.Click += new System.EventHandler(this.BuyIPOShares);
                        button.CommandName = player.Name;
                        button.CommandArgument = company.Name;
                        button.ToolTip = "Buy a share of " + company.Name + " from the IPO";
                    }

                    button.Text = nIPOShares.ToString();
                    bEnabled = player.Priority && !bSoldShares && nIPOShares > 0 && !game.ForcedStockSalePending;
                    button.Enabled = bEnabled && !player.PurchasedSomething;

                    // set company OpenMarket shares
                    sCompany = company.Name;
                    sCompany += "OpenMarket";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (tableCell.Controls.Count > 0)
                    {
                        button = tableCell.Controls[0] as Button;
                    }
                    else
                    {
                        button = new Button();
                        tableCell.Controls.Add(button);
                        button.Click += new System.EventHandler(this.BuyBankShares);
                        button.CommandName = player.Name;
                        button.CommandArgument = company.Name;
                        button.ToolTip = "Buy a share of " + company.Name + " from the Open Market";
                    }

                    button.Text = nBankPoolShares.ToString();
                    bEnabled = player.Priority && !bSoldShares && nBankPoolShares > 0 && !game.ForcedStockSalePending;
                    button.Enabled = bEnabled && !player.PurchasedSomething;

                    // set company cash
                    sCompany = company.Name;
                    sCompany += "Cash";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (company.StockMarketPosition != null)	// is the company open?
                        tableCell.Text = nCash.ToString();

                    // set company escrow
                    sCompany = company.Name;
                    sCompany += "Escrow";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (company.StockMarketPosition != null)	// is the company open?
                        tableCell.Text = nEscrow.ToString();

                    // set company loans
                    sCompany = company.Name;
                    sCompany += "Loans";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (company.StockMarketPosition != null)	// is the company open?
                        tableCell.Text = nLoans.ToString();

                    // set company last dividend
                    sCompany = company.Name;
                    sCompany += "LastDividend";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (company.StockMarketPosition != null)	// is the company open?
                        tableCell.Text = company.LastDividend.ToString();

                    // set company privates
                    sCompany = company.Name;
                    sCompany += "Privates";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (tableCell.Controls.Count == 0)
                    {
                        foreach (PrivateCompany privateCompany in company.PrivateCompanies)
                        {
                            button = new Button();
                            button.Text = privateCompany.NickName;
                            button.Enabled = false;
                            button.ToolTip = privateCompany.Name + "\n" + "Cost: " + privateCompany.Cost + "\n" + "Income: " + privateCompany.Income;
                            tableCell.Controls.Add(button);
                        }
                    }

                    if (tableCell.Controls.Count == 0) // JWF Kludge to work around text from above being scrolled down when rows are added.
                    {
                        tableCell.Text = "";
                    }

                    // set company trains
                    sCompany = company.Name;
                    sCompany += "Trains";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (tableCell.Controls.Count == 0)
                    {
                        if (company.StockMarketPosition != null)
                        {
                            foreach (Train train in company.Trains)
                            {
                                button = new Button();
                                button.Text = train.Name;
                                button.Enabled = false;
                                tableCell.Controls.Add(button);
                            }
                        }
                    }

                    if (tableCell.Controls.Count == 0) // JWF Kludge to work around text from above being scrolled down when rows are added.
                    {
                        tableCell.Text = "";
                    }

                    // set company tokens
                    sCompany = company.Name;
                    sCompany += "Stations";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);
                    sTokens = nTokensPlayed.ToString() + "/" + nTokens.ToString();
                    tableCell.Text = sTokens;

                    // set company loans
                    sCompany = company.Name;
                    sCompany += "Loans";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (company.StockMarketPosition != null)	// is the company open?
                        tableCell.Text = nLoans.ToString();

                    // set company current stock market value
                    sCompany = company.Name;
                    sCompany += "CurrentValue";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (company.StockMarketPosition != null)	// is the company open?
                        tableCell.Text = nCurrentValue.ToString();

                    // set company par price
                    sCompany = company.Name;
                    sCompany += "ParPrice";

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);

                    if (company.StockMarketPosition != null)	// is the company open?
                        tableCell.Text = nParPrice.ToString();

                    // set company notes
                    sCompany = company.Name;
                    sCompany += "Notes";

                    string sNotes = "";

                    if (company.PortRights)
                        sNotes += "Port";

                    if (company.BridgeRights)
                    {
                        if (sNotes.Length > 0)
                            sNotes += ", ";

                        sNotes += "Bridge";
                    }

                    if (company.TunnelRights)
                    {
                        if (sNotes.Length > 0)
                            sNotes += ", ";

                        sNotes += "Tunnel";
                    }

                    tableCell = (TableCell)GameInfoTable.FindControl(sCompany);
                    tableCell.Text = sNotes;
                }

            }
            catch (Exception ex)
            {
                DisplayError("Exception, FillTableWithCompanyInfo: " + ex.Message);
            }
        }

        private void NextPlayer(bool bUpdate)
        {
            try
            {
                GivePriorityToNextPlayer();
                EnableControls(false);
                Game game = Global.getGame(this); ;
                game.UpdateAllPlayers();

                if (bUpdate)
                {
                    //			    Server.Transfer ("StockRound.aspx");   // Update my screen.
                    string sPlayer = Session["PlayerName"] as string;
                    Player player = game.Players[sPlayer];
                    DisplayStockRoundInfo(game, player);
                }
            }
            catch (Exception ex)
            {
                DisplayError("Exception, NextPlayer: " + ex.Message); 
            }
        }

        private void EverybodyPassed()
        {
            try
            {
                Game game = Global.getGame(this); ;

                game.OperatingRoundBeingInitialized = false;  // JWF 11.24.2007 Work around bug initializing operating round.

                game.History.Clear();   // JWF 11.15.2007  Helps to signal that the stock round is over for other browsers.
                game.History.Add("Go To Operating Round");
                game.FirstStockRound = false;

                // reset all player shares sold
                foreach (Player player in game.Players)
                {
                    player.PermaPass = false;
                    player.ResetShareInterRoundInfo();
                }

                // adjust stock price after SR is over
                foreach (PublicCompany company in game.PublicCompanies)
                    company.AdjustSharePriceAfterStockRound();

                game.GoToStockRound = false;
                game.AdjustOperatingRoundInfo();
                game.UpdateAllPlayers();

//                Response.Redirect("OperatingRound2.aspx");  JWF 12.1.2007  This can throw an exception.
                this.Server.Transfer("OperatingRound2.aspx");
            }
            catch (Exception ex)
            {
                DisplayError("Exception, EverybodyPassed: " + ex.Message);
            }
        }

        private void GivePriorityToNextPlayer()
        {
            try
            {
                int i = 0;
                Game game = Global.getGame(this); ;
                Player nextPlayer;

                foreach (Player player in game.Players)
                {
                    if (player.Priority)
                    {
                        player.Priority = false;
                        player.SoldSomething = false;
                        player.PurchasedSomething = false;
                        break;
                    }
                    else
                    {
                        i++;
                    }
                }

                i++;  // The player with priority is the one after the current one.

                if (i < game.Players.Count)
                    nextPlayer = (Player)game.Players[i];
                else // back to the first player.
                    nextPlayer = (Player)game.Players[0];

                nextPlayer.Priority = true;
                game.UpdateAllPlayers();
                game.SaveGame("");  //JoeB 10.15.07
            }
            catch (Exception ex)
            {
                DisplayError("Exception, GivePriorityToNextPlayer: " + ex.Message);
            }
        }


        private void SeeIfWeCanDumpCompanyOnAnotherPlayer(int nCompanyIndex, ref Player dumpPlayer, ref bool bPresident)
        {
            try
            {
                int nPos = 0;
                int nCompanyPresidentPos = 0;
                int nMaxShares = 0;
                int nCurrentPlayerShares = 0;
                Game game = Global.getGame(this);
                string sPlayer = Session["PlayerName"].ToString();
                Player player = null;
                Player sellingPlayer = null;
                Player presidentPlayer = null;

                dumpPlayer = null;
                bPresident = false;
                presidentPlayer = game.PublicCompanies[nCompanyIndex].Owner;

                // step 0.  find the player selling
                foreach (Player currentPlayer in game.Players)
                {
                    if (currentPlayer == presidentPlayer)
                        nCompanyPresidentPos = nPos;

                    if (currentPlayer.Priority)
                        sellingPlayer = currentPlayer;

                    nPos++;
                }

                // if seller is not president, then we can't dump RR so return
                if (sellingPlayer != presidentPlayer)
                    return;

                bPresident = true;

                nPos = nCompanyPresidentPos + 1;    // +1 for player to left of president

                // step 1.  next player to president to end
                while (nPos < game.Players.Count)
                {
                    player = game.Players[nPos++];
                    nCurrentPlayerShares = player._nNumShares[nCompanyIndex];

                    // must own at least 2 shares to get dumped on
                    if (nCurrentPlayerShares >= 2 && nCurrentPlayerShares > nMaxShares)
                    {
                        nMaxShares = nCurrentPlayerShares;
                        dumpPlayer = player;
                    }
                }

                nPos = 0;

                // step 2.  beginning to president
                while (nPos < nCompanyPresidentPos)
                {
                    player = game.Players[nPos++];
                    nCurrentPlayerShares = player._nNumShares[nCompanyIndex];

                    // must own at least 2 shares to get dumped on
                    if (nCurrentPlayerShares >= 2 && nCurrentPlayerShares > nMaxShares)
                    {
                        nMaxShares = nCurrentPlayerShares;
                        dumpPlayer = player;
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayError("Exception, SeeIfWeCanDumpCompanyOnAnotherPlayer: " + ex.Message);
            }
        }

        private bool DidWeStealCompanyFromAnotherPlayer(int nCompanyIndex, ref Player stealFromPlayer)
        {
            int nSharesIOwn = 0;
            bool bDidSteal = false;
            try
            {
                Game game = Global.getGame(this); ;
                string sPlayer = Session["PlayerName"].ToString();
                Player Me = null;

                stealFromPlayer = null;

                // find "Me"
                foreach (Player player in game.Players)
                {
                    if (player.Priority)
                    {
                        Me = player;
                        nSharesIOwn = player._nNumShares[nCompanyIndex] + 1;    // +1 for the one I'm buying right now
                        break;
                    }
                }

                foreach (Player player in game.Players)
                {
                    if (player.Name != Me.Name)	// can't steal from myself
                    {
                        // do I own more than the current president?
                        if (player._bPresShares[nCompanyIndex] && (nSharesIOwn > player._nNumShares[nCompanyIndex]))	// do I own more than the current president?
                        {
                            stealFromPlayer = player;
                            bDidSteal = true;
                            break;
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                DisplayError("Exception, DidWeStealCompanyFromAnotherPlayer: " + ex.Message);
            }

            return bDidSteal;
        }

        private void BuyIPOShares(object sender, System.EventArgs e)
        {
            try
            {
                Game game = Global.getGame(this); ;
                string sPlayer = Session["PlayerName"].ToString();
                Button button = (Button)sender;

                int nValue;
                int nCompanyIndex;
                int nSelectedIndex = -1;
                string sCompany;
                Player player;
                PublicCompany company;

                sCompany = button.CommandArgument;
                company = game.PublicCompanies[sCompany];
                nCompanyIndex = company.Index;

                player = game.Players[sPlayer];
                company = game.PublicCompanies[sCompany];

                nSelectedIndex = PriceDDL.SelectedIndex;
                bool bReturn = int.TryParse(PriceDDL.Items[nSelectedIndex].Value, out nValue);

                if (!player._bSoldShares[nCompanyIndex])					// haven't sold any already
                {
                    if (player.IsUnderCertificateLimit(nCompanyIndex))		// under the certificate limit
                    {
                        if (player.IsUnderCompanyShareLimit(nCompanyIndex))	// under the company limit
                        {
                            int nCashNeeded = 0;

                            if (company.Open)					// has company opened yet?
                                nCashNeeded = company.ParPrice;	// yes, need par price
                            else
                                nCashNeeded = 2 * nValue;		// no, need 2x opening price

                            if (player.Cash >= nCashNeeded)		// have the $$$
                            {
                                bool bPresidency = false;
                                string sMsg;
                                Player stealFromPlayer = null;

                                if (!company.Open)					// has company opened yet?
                                {
                                    company.ParPrice = nValue;		// set initial par price
                                    company.SetInitialStockMarketPosition();
                                }

                                company.BuyShareFromIPO(player, ref bPresidency);

                                if (bPresidency)
                                    sMsg = sPlayer + " opened the " + sCompany + " at $" + company.ParPrice;
                                else
                                    sMsg = sPlayer + " bought a share of the " + sCompany + " for $" + company.ParPrice;

                                game.History.Add(sMsg);

                                if (DidWeStealCompanyFromAnotherPlayer(nCompanyIndex, ref stealFromPlayer))
                                {
                                    player.StealCompany(stealFromPlayer, nCompanyIndex);

                                    sMsg = player.Name + " is now the new president of the " + sCompany;
                                    game.History.Add(sMsg);
                                }

                                // done buying until next turn
                                player.PurchasedSomething = true;
                                pbDone.Enabled = true;
                                UndoPB.Enabled = true;
                                pbPass.Enabled = false;
                                this.UndoPB.Enabled = true;

                                game.Passes = 0;
                                DisplayStockRoundInfo(game, player);

                                //							Response.Redirect("StockRound.aspx");
                            }
                            else
                            {
                                int nStockValue = company.ParPrice;

                                if (nStockValue == 0)	// company not open yet
                                    nStockValue = 2 * nValue;

                                DisplayError("Unable to purchase share.  You don't have sufficient funds.  The share costs: $" + nStockValue + ", player has: $" + player.Cash);
                            }
                        }
                        else
                        {
                            DisplayError("Unable to purchase share.  You would be over the company share limit.");
                        }
                    }
                    else
                    {
                        DisplayError("Unable to purchase share.  You would be over the certificate limit.");
                    }
                }
                else
                {
                    DisplayError("Unable to purchase shares in " + sCompany + " since you sold some already!");
                }

            }
            catch (Exception ex)
            {
                DisplayError("Exception, BuyIPOShares: " + ex.Message);
            }
        }

        private void BuyBankShares(object sender, System.EventArgs e)
        {
            try
            {
                Game game = Global.getGame(this); ;
                string sPlayer = Session["PlayerName"].ToString();
                Button button = (Button)sender;

                int nCompanyIndex;
                string sCompany;
                Player player;
                PublicCompany company;

                sCompany = button.CommandArgument;
                company = game.PublicCompanies[sCompany];
                nCompanyIndex = company.Index;

                player = game.Players[sPlayer];
                company = game.PublicCompanies[sCompany];

                if (!player._bSoldShares[nCompanyIndex])					// haven't sold any already
                {
                    if (player.IsUnderCertificateLimit(nCompanyIndex))		// under the certificate limit
                    {
                        if (player.IsUnderCompanyShareLimit(nCompanyIndex))	// under the company limit
                        {
                            if (player.Cash >= company.MarketValue)			// have the $$$
                            {
                                Player stealFromPlayer = null;

                                // must handle from bank pool also
                                company.BuyShareFromBank(player);

                                string sMsg = sPlayer + " bought a share of the " + sCompany + " for $" + company.MarketValue;

                                game.History.Add(sMsg);

                                if (DidWeStealCompanyFromAnotherPlayer(nCompanyIndex, ref stealFromPlayer))
                                {
                                    player.StealCompany(stealFromPlayer, nCompanyIndex);

                                    sMsg = player.Name + " is now the new president of the " + sCompany;
                                    game.History.Add(sMsg);
                                }

                                // done buying until next turn
                                player.PurchasedSomething = true;
                                pbDone.Enabled = true;
                                UndoPB.Enabled = true;
                                pbPass.Enabled = false;
                                this.UndoPB.Enabled = true;


                                game.Passes = 0;
                                DisplayStockRoundInfo(game, player);
                            }
                            else
                            {
                                DisplayError("Unable to purchase share.  You don't have sufficient funds.  Stock cost: " + company.MarketValue + ", player has: " + player.Cash);
                            }
                        }
                        else
                        {
                            DisplayError("Unable to purchase share.  You would be over the company share limit.");
                        }
                    }
                    else
                    {
                        DisplayError("Unable to purchase share.  You would be over the certificate limit.");
                    }
                }
                else
                {
                    DisplayError("Unable to purchase shares in " + sCompany + " since you sold some already!");
                }
            }
            catch (Exception ex)
            {
                DisplayError("Exception, BuyBankShares: " + ex.Message); 
            }
        }

        private void SellShares(object sender, System.EventArgs e)
        {
            try
            {
                Game game = Global.getGame(this); ;
                string sPlayer = Session["PlayerName"].ToString();
                Button button = (Button)sender;

                int nValue;
                int nCompanyIndex;
                int nMaxOMShares = 5;    // could be 5 or 10 depending on half or full shares
                int nSharesInBank = 0;
                int nSharesToSell = 0;
                bool bCanSellShares = false;
                bool bCanDumpCompany = false;
                bool bWouldTransfer = false;
                bool bPresident = false;
                string sCompany = "";
                Player player = null;
                Player dumpPlayer = null;
                PublicCompany company = null;

                sCompany = button.CommandArgument;
                company = game.PublicCompanies[sCompany];
                nCompanyIndex = company.Index;

                player = game.Players[sPlayer];
                company = game.PublicCompanies[sCompany];

                bool bReturn = int.TryParse(SellDDL.Items[SellDDL.SelectedIndex].Value, out nSharesToSell);

                if (!bReturn)
                    return;

                nValue = company.MarketValue;
                nSharesInBank = company.OpenMarketShares.Count;

                if (!game.FirstStockRound)											// is it NOT the 1st stock round
                {
                    if (true)   // company.Floated)											// has company floated (sold correct # of shares)
                    {
                        if (player._nNumShares[nCompanyIndex] > 0)					// must own some shares of it
                        {
                            if (player._nNumShares[nCompanyIndex] >= nSharesToSell)	// must own at least that many
                            {
                                // only applies to CGR but we might need to adjust 50% from 5 to 10 shares
                                if (!company.FullShares)
                                    nMaxOMShares = 10;

                                if (nSharesToSell <= (nMaxOMShares - nSharesInBank))
                                {
                                    // see if we can dump the company on someone else
                                    SeeIfWeCanDumpCompanyOnAnotherPlayer(nCompanyIndex, ref dumpPlayer, ref bPresident);

                                    // does someone owe more that 2 shares besides me?
                                    bCanDumpCompany = dumpPlayer != null;
                                    bWouldTransfer = false;

                                    // if we have a target, check if it would tranfer presidency
                                    if (bCanDumpCompany)
                                        bWouldTransfer = ((player._nNumShares[nCompanyIndex] - nSharesToSell) < dumpPlayer._nNumShares[nCompanyIndex]);

                                    // if we can dump but aren't transfering, then set dump president as none
                                    if (bCanDumpCompany && !bWouldTransfer)
                                        dumpPlayer = null;

                                    // we can sell these shares if...
                                    // 1. we are not the president
                                    // 2. we are the president and not forced sale (can't transfer presidency)
                                    // 3. we are the presidnt, a forced sale but not of the selling RR
                                    // 4. we are the president but not transfering
                                    bCanSellShares = ((!bPresident) ||
                                                        (bPresident && bWouldTransfer && bCanDumpCompany && !game.ForcedStockSalePending) ||
                                                        (bPresident && bWouldTransfer && bCanDumpCompany && game.ForcedStockSalePending && game.ForcedStockSaleCompany.Index != nCompanyIndex) ||
                                                        (bPresident && !bWouldTransfer && (player._nNumShares[nCompanyIndex] - nSharesToSell) >= 2));

                                    if (bCanSellShares)
                                    {
                                        int nSharePrice = company.MarketValue;
                                        bool bOverCompanyLimit = false;
                                        string sMsg;

                                        // actually sell the shares into the bank pool/another players hand if dumping
                                        player.SellShares(dumpPlayer, nCompanyIndex, nSharesToSell, true);

                                        company.AdjustSharePriceAfterSale(nSharesToSell);

                                        sMsg = sPlayer + " sold " + nSharesToSell + " share(s) of the " + sCompany + " at $ " + nSharePrice;

                                        game.History.Add(sMsg);

                                        if (dumpPlayer != null && bWouldTransfer)
                                        {
                                            sMsg = dumpPlayer.Name + " is now the new president of the " + sCompany;

                                            game.History.Add(sMsg);
                                        }

                                        // done (maybe) until next turn
                                        player.SoldSomething = true;

                                        // update forced stock sale variables
                                        if (game.ForcedStockSalePending)
                                            game.ForcedStockSaleAmountSold += (nSharesToSell * nSharePrice);

                                        // check if player still over limit, if so warn...if not, allow done
                                        for (int i = 0; i < game.PublicCompanies.Count; i++)
                                        {
                                            if (player.IsOverCompanyShareLimit(i))
                                            {
                                                pbDone.Enabled = false;

                                                DisplayError ("You are over the 60% company share limit of " + game.PublicCompanies[i].Name + " and must sell shares.");

                                                bOverCompanyLimit = true;
                                            }
                                        }

                                        // if we didn't fail company share limit, check overall certificate limit
                                        if (!bOverCompanyLimit)
                                        {
                                            // check if player still over limit, if so warn...if not, allow done
                                            if (player.IsOverCertificateLimit())
                                            {
                                                pbDone.Enabled = false;

                                                DisplayError ("You are over the certificate limit and must sell shares.");
                                            }
                                            else
                                            {
                                                pbDone.Enabled = true;

                                                DisplayError ("");
                                            }
                                        }

                                        pbPass.Enabled = false;
                                        UndoPB.Enabled = true;

                                        game.Passes = 0;

                                        DisplayStockRoundInfo(game, player);
                                        //									Response.Redirect("StockRound.aspx");
                                    }
                                    else
                                    {
                                        DisplayError ("Unable to sell " + nSharesToSell + " shares of " + sCompany + " since no one else can become president!");
                                    }
                                }
                                else
                                {
                                    DisplayError ("Unable to sell " + nSharesToSell + " shares of " + sCompany + " since the bank pool would contain > 50%!");
                                }
                            }
                            else
                            {
                                DisplayError ("Unable to sell " + nSharesToSell + " shares of " + sCompany + " since you don't own that many!");
                            }
                        }
                        else
                        {
                            DisplayError ("Unable to sell shares of " + sCompany + " since you don't own any!");
                        }
                    }
                    else
                    {
                        DisplayError ("Unable to sell shares of " + sCompany + " since the company hasn't been floated yet!");
                    }
                }
                else
                {
                    DisplayError("Unable to sell any shares during the first stock round of the game");
                }

            }
            catch (Exception ex)
            {
                DisplayError ("Exception, SellShares: " + ex.Message);
            }
        }

        private void DisplayError(string sError)
        {
            stockRoundError.Text = sError;
            stockRoundError.Visible = true;
        }

        private void BuyPrivate(object sender, System.EventArgs e)
        {
            try
            {
                Game game = Global.getGame(this); ;
                string sPlayer = Session["PlayerName"].ToString();
                Button button = (Button)sender;

                string sBuyer = sPlayer;
                string sSeller;
                string sPrivate;
                Player buyer = null;
                Player seller = null;
                PrivateCompany company = null;

                sSeller = button.CommandName;
                sPrivate = button.CommandArgument;

                buyer = game.Players[sBuyer];
                seller = game.Players[sSeller];
                company = seller.PrivateCompanies[sPrivate];

                // redirect to another page to between buyer & seller to agree on price for private
                game.ResetPrivateSaleInfo();
                game.PrivateCompanySale = true;
                game.PrivateCompanySold = false;
                game.PrivateCompanySalePrice = 0;
                game.PrivateCompanyBuyer = buyer;
                game.PrivateCompanySeller = seller;
                game.PrivateCompanyForSale = company;
                game.PrivateCompanyBuyingCompany = null;
                game.PrivateCompanyPriorityPlayerName = sBuyer;

//                Response.Redirect("PlayerBuyPrivateCompany.aspx");	// redirect buyer to buy screen  JWF 12.1.2007  This could throw an exception.
                this.Server.Transfer("PlayerBuyPrivateCompany.aspx");
            }
            catch (Exception ex)
            {
                DisplayError ("Exception, BuyPrivate: " + ex.Message);
            }
        }

        protected void pbDone_Click(object sender, System.EventArgs e)
        {
            try
            {
                Game game = Global.getGame(this);

                if (game.ForcedStockSalePending)
                {
                    bool forcedSaleFulfilled = (game.ForcedStockSaleAmountSold >= game.ForcedStockSaleAmountNeeded);
                    bool CanSellShares = true;
                    if (!forcedSaleFulfilled)	// do the deep check only if needed
                        CanSellShares = game.ForcedStockSalePlayer.CanSellAnyShares();

                    // we have completed the forced sale now see what happens (success or bankrupcy)
                    if (forcedSaleFulfilled || (!CanSellShares))
                    {
                        string sMsg;
                        if ((!forcedSaleFulfilled) && (!CanSellShares))
                        {
                            sMsg = "Unable to completed forced stock sale; " +
                                game.ForcedStockSalePlayer.Name + " is going bankrupt";

                            // zero out the player's cash in preparation for the bankrupcy
                            game.Bank += game.ForcedStockSalePlayer.Cash;
                            game.ForcedStockSalePlayer.Cash = 0;
                        }
                        else
                            sMsg = "Forced stock sale is over for " + game.ForcedStockSalePlayer.Name;

                        game.ForcedStockSaleFullfilled = forcedSaleFulfilled;

                        game.ForcedStockSaleCompleted = true;
                        game.GoToStockRound = false;
                        game.UpdateAllPlayers();
                        game.History.Add(sMsg);

                        Server.Transfer("OperatingRound2.aspx");
                    }
                    else
                    {
                        // not enough cash raised yet
                        int stillNeed = game.ForcedStockSaleAmountNeeded - game.ForcedStockSaleAmountSold;
                        DisplayError ("Not finished yet! You still need to raise $" + stillNeed +
                            ".\nYou must sell stock to raise $" + game.ForcedStockSaleAmountNeeded.ToString() +
                            " and you have sold $" + game.ForcedStockSaleAmountSold.ToString() + " so far.");
                    }
                }
                else
                {
                    NextPlayer(true);
                }
            }
            catch (Exception ex)
            {
                DisplayError ("Exception, pbDone_Click: " + ex.Message); 
            }
        }

        protected void pbPass_Click(object sender, System.EventArgs e)
        {
            DoPass(true);
        }

        private void DoPass(bool bUpdate)
        {
            try
            {
                Game game = Global.getGame(this); ;
                string sPlayer = Session["PlayerName"].ToString();
                string sPass;

                sPass = sPlayer + " passed";
                game.History.Add(sPass);
                game.Passes++;

                if (game.Passes >= game.Players.Count) // Has everybody passed?  JWF 11.24.2007 Should never be > but working around a bug.
                {
                    GivePriorityToNextPlayer();

                    game.Passes = 0;
                    EverybodyPassed();
                }

                NextPlayer(bUpdate);
            }
            catch (Exception ex)
            {
                DisplayError ("Exception, DoPass: " + ex.Message);
            }
        }

        protected void StockMarket_Click(object sender, System.EventArgs e)
        {
            try
            {
                Game game = Global.getGame(this); ;

                game.ViewStockMarketFromStockRound = true;
                Response.Redirect("StockMarket.aspx");  // JWF 12.1.2007  This could throw an exception
//                this.Server.Transfer("StockMarket.aspx");
            }
            catch (Exception ex)
            {
                DisplayError ("Exception, StockMarket_Click: " + ex.Message);
            }
        }

        protected void GameStatus_Click(object sender, System.EventArgs e)
        {
            try
            {
                Game game = Global.getGame(this); ;

                game.ViewGameStatusFromStockRound = true;
                Response.Redirect("GameStatus.aspx");
//                this.Server.Transfer("GameStatus.aspx");
            }
            catch (Exception ex)
            {
                DisplayError ("Exception, GameStatus_Click: " + ex.Message);
            }
        }

        protected void UndoPB_Click(object sender, EventArgs e)
        {
            this.UndoPB.Enabled = false;

            try
            {
                Game game = Global.getGame(this);

                if (!File.Exists(game.PathOfLastSavedGame))
                {
                    DisplayError ("Can't undo because file: " + game.PathOfLastSavedGame + " doesn't exist");
                }

                Game restoredGame = Game.LoadGame(game.PathOfLastSavedGame);

                if (restoredGame != null)
                {
                    string sPlayer = Session["PlayerName"] as string;
                    Player player = restoredGame.Players[sPlayer];
                    
                    restoredGame.History.Add("Undo done by: " + sPlayer);
                    restoredGame.PathOfLastSavedGame = game.PathOfLastSavedGame;
                    Global.ReplaceGame(this, restoredGame);
                    DisplayStockRoundInfo(restoredGame, player);
                }
            }
            catch (Exception ex)
            {
                DisplayError ("Exception during Undo: " + ex.Message);
            }
        }


        protected void PermaPass_CheckedChanged1(object sender, EventArgs e)
        {
            try
            {
                Game game = Global.getGame(this);
                string sPlayer = Session["PlayerName"].ToString();
                Player player = game.Players[sPlayer];

                player.PermaPass = this.PermaPass.Checked;

            }
            catch (Exception ex)
            {
                DisplayError ("Exception during PermaPass Checkbox:" + ex.Message);
            }
            //            player.PermaPass = !player.PermaPass;
        }
    }
}




